local timeLeft = 10
local timeLeft2 = 10
local stormOn = false
local zombieOn = false
local maxZombie = 10

VoteCopOn = false

function ControlZombie()
	timeLeft2 = timeLeft2 - 1

	if (timeLeft2 < 1) then
		if (zombieOn == true) then
			timeLeft2 = math.random(300,500)
			zombieOn = false
			timer.Stop("start2")
			ZombieEnd()
		else
			timeLeft2 = math.random(150,300)
			zombieOn = true
			timer.Start("start2")
			DB.RetrieveZombies()
			ZombieStart()
		end
	end
end

function ZombieStart()
	for k, v in pairs(player.GetAll()) do
		if (v:Alive()) then
			v:PrintMessage(HUD_PRINTCENTER, "WARNING! Zombies Are Approaching!")
			v:PrintMessage(HUD_PRINTTALK, "WARNING! Zombies Are Approaching!")
		end
	end
end

function ZombieEnd()
	for k, v in pairs(player.GetAll()) do
		if (v:Alive()) then
			v:PrintMessage(HUD_PRINTCENTER, "Zombies Are Leaving.")
			v:PrintMessage(HUD_PRINTTALK, "Zombies Are Leaving.")
		end
	end
end

function StormStart()
	for k, v in pairs(player.GetAll()) do
		if (v:Alive()) then
			v:PrintMessage(HUD_PRINTCENTER, "WARNING! Meteor Storm Approaching!")
			v:PrintMessage(HUD_PRINTTALK, "WARNING! Meteor Storm Approaching!")
		end
	end
end

function StormEnd()
	for k, v in pairs(player.GetAll()) do
		if (v:Alive()) then
			v:PrintMessage(HUD_PRINTCENTER, "Meteor Storm Passing.")
			v:PrintMessage(HUD_PRINTTALK, "Meteor Storm Passing.")
		end
	end
end

function ControlStorm()
	timeLeft = timeLeft - 1

	if (timeLeft < 1) then
		if (stormOn == true) then
			timeLeft = math.random(300,500)
			stormOn = false
			timer.Stop("start")
			StormEnd()
		else
			timeLeft = math.random(60,90)
			stormOn = true
			timer.Start("start")
			StormStart()
		end
	end
end

function StartShower()
	timer.Adjust("start", math.random(.5,1.5), 0, StartShower)
	for k, v in pairs(player.GetAll()) do
		if (math.random(0, 2) == 0) then
			if (v:Alive()) then
				AttackEnt(v)
			end
		end
	end
end

function DrugPlayer(pl)
	pl:ConCommand("pp_motionblur 1")
	pl:ConCommand("pp_motionblur_addalpha 0.05")
	pl:ConCommand("pp_motionblur_delay 0.035")
	pl:ConCommand("pp_motionblur_drawalpha 1.00")
	pl:ConCommand("pp_dof 1")
	pl:ConCommand("pp_dof_initlength 9")
	pl:ConCommand("pp_dof_spacing 8")

	local IDSteam = string.gsub(pl:SteamID(), ":", "")

	timer.Create(IDSteam, 40, 1, UnDrugPlayer, pl)
end

function UnDrugPlayer(pl)
	pl:ConCommand("pp_motionblur 0")
	pl:ConCommand("pp_dof 0")
end

function AttackEnt(ent)
	meteor = ents.Create("meteor")
	meteor.nodupe = true
	meteor:Spawn()
	meteor:SetTarget(ent)
end

function PlayerDist(npcPos)
	local playDis
	local currPlayer
	for k, v in pairs(player.GetAll()) do
		local tempPlayDis = v:GetPos():Distance(npcPos:GetPos())

		if (playDis == nil) then
			playDis = tempPlayDis
			currPlayer = v
		end

		if (tempPlayDis < playDis) then
			playDis = tempPlayDis
			currPlayer = v
		end
	end

	return currPlayer
end

function MoveZombie()
	local activePlayers = false

	for k, v in pairs(player.GetAll()) do
		activePlayers = true
	end

	if (activePlayers == true) then
		local tb1 = table.Add(ents.FindByClass("npc_antlion"),ents.FindByClass("npc_fastzombie"))
		local tb2 = table.Add(ents.FindByClass("npc_zombie"),ents.FindByClass("npc_headcrab_fast"))
		local tb3 = table.Add(tb1,tb2)
		local tb4 = table.Add(tb3,ents.FindByClass("npc_headcrab"))

		for a, b in pairs(tb4) do
			local newpos = b:GetPos() + ((PlayerDist(b):GetPos()-b:GetPos()):Normalize()*500)

			if (PlayerDist(b):GetPos():Distance(b:GetPos()) > 500) then
				b:AddEntityRelationship(PlayerDist(b), 1, 99)
				b:SetLastPosition(newpos)
				b:SetSchedule(71)
			end
		end
	end
	timer.Create("move", .5, 0, MoveZombie)
	timer.Stop("move")
end

function LoadTable(ply)
	ply:SetNWInt("numPoints", table.getn(zombieSpawns))

	for k, v in pairs(zombieSpawns) do
		local Sep = (string.Explode(" " ,v))
		ply:SetNWVector("zPoints" .. k, Vector(tonumber(Sep[1]),tonumber(Sep[2]),tonumber(Sep[3])))
	end
end

function ReMoveZombie(ply, index)
	if (ply:HasPriv(ADMIN)) then
		if not index or zombieSpawns[tonumber(index)] == nil then
			Notify(ply, 1, 3, "Zombie Spawn " .. tostring(index) .. " does not exist.")
		else
			DB.RetrieveZombies()
			Notify(ply, 1, 3, "Zombie spawn removed.")
			table.remove(zombieSpawns,index)
			DB.StoreZombies()
			if (ply:GetNWBool("zombieToggle") == true) then
				LoadTable(ply)
			end
		end
	else
		Notify(ply, 1, 3, "Must be an admin.")
	end
	return ""
end
AddChatCommand("/removezombie", ReMoveZombie)

function AddZombie(ply)
	if ply:HasPriv(ADMIN) then
		DB.RetrieveZombies()
		table.insert(zombieSpawns, tostring(ply:GetPos()))
		DB.StoreZombies()
		if (ply:GetNWBool("zombieToggle") == true) then LoadTable(ply) end
		Notify(ply, 1, 3, "Zombie spawn added.")
	else
		Notify(ply, 1, 3, "Must be an admin.")
	end
	return ""
end
AddChatCommand("/addzombie", AddZombie)

function ToggleZombie(ply)
	if (ply:HasPriv(ADMIN)) then
		if (ply:GetNWBool("zombieToggle") == false) then
			DB.RetrieveZombies()
			ply:SetNWBool("zombieToggle", true)
			LoadTable(ply)
			Notify(ply, 1, 3, "Show Zombies Enabled")
		else
			ply:SetNWBool("zombieToggle", false)
			Notify(ply, 1, 3, "Show Zombies Disabled")
		end
	else
		Notify(ply, 1, 3, "Must be an admin.")
	end
	return ""
end
AddChatCommand("/showzombie", ToggleZombie)

function SpawnZombie()
	timer.Start("move")
	if (GetAliveZombie() < maxZombie) then
		if (table.getn(zombieSpawns) > 0) then
			local zombieType = math.random(2, 2)
			if (zombieType == 1) then
				local zombie1 = ents.Create("npc_zombie")
				zombie1:SetPos(DB.RetrieveRandomZombieSpawnPos())
				zombie1.nodupe = true
				zombie1:Spawn()
				zombie1:Activate()
			elseif (zombieType == 2) then
				local zombie2 = ents.Create("npc_fastzombie")
				zombie2:SetPos(DB.RetrieveRandomZombieSpawnPos())
				zombie2.nodupe = true
				zombie2:Spawn()
				zombie2:Activate()
			elseif (zombieType == 3) then
				local zombie3 = ents.Create("npc_antlion")
				zombie3:SetPos(DB.RetrieveRandomZombieSpawnPos())
				zombie3.nodupe = true
				zombie3:Spawn()
				zombie3:Activate()
			elseif (zombieType == 4) then
				local zombie4 = ents.Create("npc_headcrab_fast")
				zombie4:SetPos(DB.RetrieveRandomZombieSpawnPos())
				zombie4.nodupe = true
				zombie4:Spawn()
				zombie4:Activate()
			end
		end
	end
end

function GetAliveZombie()
	local zombieCount = 0

	for k, v in pairs(ents.FindByClass("npc_zombie")) do
		zombieCount = zombieCount + 1
	end

	for k, v in pairs(ents.FindByClass("npc_fastzombie")) do
		zombieCount = zombieCount + 1
	end

	for k, v in pairs(ents.FindByClass("npc_antlion")) do
		zombieCount = zombieCount + 1
	end

	for k, v in pairs(ents.FindByClass("npc_headcrab_fast")) do
		zombieCount = zombieCount + 1
	end

	return zombieCount
end

function dropWeapon(ply)
	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	local tr = util.TraceLine(trace)
	local ent = ply:GetActiveWeapon()
	if (ent:GetClass() == "weapon_deagle2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_deagle.mdl")
		weapon:SetNWString("weaponclass", "weapon_deagle2")
		weapon:SetPos(tr.HitPos)
		weapon:SetNWString("Owner", "Shared")
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_fiveseven2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_fiveseven.mdl")
		weapon:SetNWString("weaponclass", "weapon_fiveseven2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_glock2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_glock18.mdl")
		weapon:SetNWString("weaponclass", "weapon_glock2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_ak472") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_rif_ak47.mdl")
		weapon:SetNWString("weaponclass", "weapon_ak472")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_mp52") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_smg_mp5.mdl")
		weapon:SetNWString("weaponclass", "weapon_mp52")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_m42") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_rif_m4a1.mdl")
		weapon:SetNWString("weaponclass", "weapon_m42")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_mac102") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_smg_mac10.mdl")
		weapon:SetNWString("weaponclass", "weapon_mac102")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_para2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_mach_m249para.mdl")
		weapon:SetNWString("weaponclass", "weapon_para2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_pumpshotgun2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_shot_m3super90.mdl")
		weapon:SetNWString("weaponclass", "weapon_pumpshotgun2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_tmp2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_smg_tmp.mdl")
		weapon:SetNWString("weaponclass", "weapon_tmp2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "ls_sniper") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_snip_g3sg1.mdl")
		weapon:SetNWString("weaponclass", "ls_sniper")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_usp2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_usp.mdl")
		weapon:SetNWString("weaponclass", "weapon_usp2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_p2282") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_p228.mdl")
		weapon:SetNWString("weaponclass", "weapon_p2282")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_p90") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_smg_p90.mdl")
		weapon:SetNWString("weaponclass", "weapon_p90")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (ent:GetClass() == "weapon_knife2") then
		ply:StripWeapon(ent:GetClass())
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_knife_t.mdl")
		weapon:SetNWString("weaponclass", "weapon_knife2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	else
		Notify(ply, 1, 3, "You can only drop Approved Weapons!")
	end
	return ""
end
AddChatCommand("/drop", dropWeapon)
AddChatCommand("/dropweapon", dropWeapon)
AddChatCommand("/weapondrop", dropWeapon)

function zombieMax(ply, args)
	if (ply:HasPriv(ADMIN)) then
		maxZombie = tonumber(args)
		Notify(ply, 1, 3, "Max Zombies set")
	end

	return ""
end
AddChatCommand("/zombiemax", zombieMax)

function unWarrant(ply, target)
	target:SetNWBool("warrant", false)
	Notify(ply, 1, 3, "Search warrant for " .. target:Nick() .. " has expired!")
end

function setWarrant(ply, target)
	target:SetNWBool("warrant", true)
	timer.Simple(CfgVars["searchtime"], unWarrant, ply, target)
	for a, b in pairs(player.GetAll()) do
		b:PrintMessage(HUD_PRINTCENTER, "Search warrant approved for " .. target:Nick() .. "!")
	end
	Notify(ply, 1, 3, "Warrant set")
end

function finishWarrant(choice, mayor, initiator, target)
	if (choice == 1) then
		setWarrant(initiator, target)
	else
		Notify(initiator, 1, 3, "Mayor " .. mayor:Nick() .. " has denied your search warrant request.")
	end
	return ""
end

function searchWarrant(ply, args)
	local t = ply:Team()
	if not (t == TEAM_POLICE or t == TEAM_MAYOR or t == TEAM_CHIEF) then
		Notify(ply, 1, 3, "You must be a Cop or the Mayor.")
	else
		local p = FindPlayer(args)
		if (p and p:Alive()) then
			-- If we're the Mayor, set the search warrant
			if t == TEAM_MAYOR then
				setWarrant(ply, p)
			else -- If we're CP or Chief
				-- Find the mayor
				local m = nil
				for k, v in pairs(player.GetAll()) do
					if v:Team() == TEAM_MAYOR then
						m = v
						break
					end
				end
				-- If we found the mayor
				if m ~= nil then
					-- request a search warrent for player "p"
					ques:Create(ply:Nick() .. " wants a search warrant for " .. p:Nick(), p:EntIndex() .. "warrant", m, 40, finishWarrant, ply, p)
					Notify(ply, 1, 3, "Search warrant request sent to Mayor " .. m:Nick() .. "!")
				else
					-- there is no mayor, CPs can set warrants.
					setWarrant(ply, p)
				end
			end
		else
			Notify(ply, 1, 3, "Player is dead or does not exist.")
		end
	end
	return ""
end
AddChatCommand("/warrant", searchWarrant)
AddChatCommand("/warrent", searchWarrant) -- Most players can't spell for some reason

function playerWanted(ply, args)
	local t = ply:Team()
	if not (t == TEAM_POLICE or t == TEAM_MAYOR or t == TEAM_CHIEF) then
		Notify(ply, 1, 3, "You must be a Cop or the Mayor.")
	else
		local p = FindPlayer(args)
		if (p and p:Alive()) then
			p:SetNWBool("wanted", true)
			for a, b in pairs(player.GetAll()) do
				b:PrintMessage(HUD_PRINTCENTER, p:Nick() .. " is wanted by the Police!")
			end
		else
			Notify(ply, 1, 3, "Player is dead or does not exist.")
		end
	end
	return ""
end
AddChatCommand("/wanted", playerWanted)

function playerUnWanted(ply, args)
	local t = ply:Team()
	if not (t == TEAM_POLICE or t == TEAM_MAYOR or t == TEAM_CHIEF) then
		Notify(ply, 1, 3, "You must be a Cop or the Mayor.")
	else
		local p = FindPlayer(args)
		if (p and p:Alive()) then
			p:SetNWBool("wanted", false)
			for a, b in pairs(player.GetAll()) do
				b:PrintMessage(HUD_PRINTCENTER, p:Nick() .. " is no longer wanted by the Police.")
			end
		else
			Notify(ply, 1, 3, "Player is dead or does not exist.")
		end
	end
	return ""
end
AddChatCommand("/unwanted", playerUnWanted)

function SetSpawnPos(ply, args)
	if not ply:HasPriv(ADMIN) and not ply:IsAdmin() and not ply:IsSuperAdmin() then return "" end

	local pos = string.Explode(" ", tostring(ply:GetPos()))
	local selection = "citizen"
	local t = 99

	if (args == "citizen") then
		t = TEAM_CITIZEN
		Notify(ply, 1, 4,  "Citizen Spawn Position set.")
	elseif (args == "cp") then
		t = TEAM_POLICE
		Notify(ply, 1, 4,  "CP Spawn Position set.")
	elseif (args == "mayor") then
		t = TEAM_MAYOR
		Notify(ply, 1, 4,  "Mayor Spawn Position set.")
	elseif (args == "gangster") then
		t = TEAM_GANG
		Notify(ply, 1, 4,  "Gangster Spawn Position set.")
	elseif (args == "mobboss") then
		t = TEAM_MOB
		Notify(ply, 1, 4,  "Mob Boss Spawn Position set.")
	elseif (args == "gundealer") then
		t = TEAM_GUN
		Notify(ply, 1, 4,  "Gun Dealer Spawn Position set.")
	elseif (args == "medic") then
		t = TEAM_MEDIC
		Notify(ply, 1, 4,  "Medic Spawn Position set.")
	elseif (args == "cook") then
		t = TEAM_COOK
		Notify(ply, 1, 4,  "Cook Spawn Position set.")
	elseif (args == "chief") then
		t = TEAM_CHIEF
		Notify(ply, 1, 4,  "Chief Spawn Position set.")
	end

	if t ~= 99 then
		DB.StoreTeamSpawnPos(t, pos)
	end

	return ""
end
AddChatCommand("/setspawn", SetSpawnPos)

function startStorm(ply)
	if (ply:HasPriv(ADMIN)) then
		timer.Start("stormControl")
		Notify(ply, 1, 3, "Meteor Storm Enabled")
	end
	return ""
end
AddChatCommand("/enablestorm", startStorm)

function helpCop(ply)
	if (ply:GetNWBool("helpCop") == true) then
		ply:SetNWBool("helpCop",false)
	else
		ply:SetNWBool("helpCop",true)
	end
	return ""
end
AddChatCommand("/cophelp", helpCop)

function helpMayor(ply)
	if (ply:GetNWBool("helpMayor") == true) then
		ply:SetNWBool("helpMayor",false)
	else
		ply:SetNWBool("helpMayor",true)
	end
	return ""
end
AddChatCommand("/mayorhelp", helpMayor)

function helpZombie(ply)
	if (ply:GetNWBool("helpZombie") == true) then
		ply:SetNWBool("helpZombie",false)
	else
		ply:SetNWBool("helpZombie",true)
	end
	return ""
end
AddChatCommand("/zombiehelp", helpZombie)

function helpBoss(ply)
	if (ply:GetNWBool("helpBoss") == true) then
		ply:SetNWBool("helpBoss",false)
	else
		ply:SetNWBool("helpBoss",true)
	end
	return ""
end
AddChatCommand("/mobbosshelp", helpBoss)

function helpAdmin(ply)
	if (ply:GetNWBool("helpAdmin") == true) then
		ply:SetNWBool("helpAdmin",false)
	else
		ply:SetNWBool("helpAdmin",true)
	end
	return ""
end
AddChatCommand("/adminhelp", helpAdmin)

function closeHelp(ply)
	ply:SetNWBool("helpCop", false)
	ply:SetNWBool("helpBoss", false)
	ply:SetNWBool("helpMayor", false)
	ply:SetNWBool("helpZombie", false)
	ply:SetNWBool("helpAdmin", false)
	return ""
end
AddChatCommand("/x", closeHelp)

function removeItem(ply)
	local trace = ply:GetEyeTrace()
	if ValidEntity(trace.Entity) and trace.Entity.SID and (ply:HasPriv(ADMIN) or trace.Entity.SID == ply.SID) then
		trace.Entity:Remove()
	end
	return ""
end
AddChatCommand("/rm", removeItem)

function removeLetters(ply)
	for k, v in pairs(ents.FindByClass("letter")) do
		print("Letter SID: " .. tostring(v.SID) .. "\nPlayer SID: " .. tostring(ply.SID))
		if v.SID == ply.SID then v:Remove() end
	end
	Notify(ply, 1, 3, "Your letters were cleaned up")
	return ""
end
AddChatCommand("/removeletters", removeLetters)

function stopStorm(ply)
	if (ply:HasPriv(ADMIN)) then
		timer.Stop("stormControl")
		stormOn = false
		timer.Stop("start")
		StormEnd()
		Notify(ply, 1, 3, "Meteor Storm Disabled")
		return ""
	end
end
AddChatCommand("/disablestorm", stopStorm)

function startZombie(ply)
	if (ply:HasPriv(ADMIN)) then
		timer.Start("zombieControl")
		Notify(ply, 1, 3, "Zombies Enabled")
	end
	return ""
end
AddChatCommand("/enablezombie", startZombie)

function stopZombie(ply)
	if (ply:HasPriv(ADMIN)) then
		timer.Stop("zombieControl")
		zombieOn = false
		timer.Stop("start2")
		ZombieEnd()
		Notify(ply, 1, 3, "Zombies Disabled")
		return ""
	end
end
AddChatCommand("/disablezombie", stopZombie)

function queryVar(ply, args)
	if not CfgVars[args] then
		Notify(ply, 1, 3, "CfgVar " .. args .. " not found.")
	else
		Notify(ply, 1, 3, args .. " = " .. CfgVars[args])
	end
	return ""
end
AddChatCommand("/queryvar", queryVar)

function SetPrice(ply, args)
	if (args == "") then return "" end

	local a = tonumber(args)
	if not a then return "" end
	local b = math.floor(a)
	if b < 0 then return "" end
	local trace = {}

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	local tr = util.TraceLine(trace)

	if ValidEntity(tr.Entity) and (tr.Entity:GetNWBool("gunlab") or tr.Entity:GetNWBool("microwave")) and tr.Entity.SID == ply.SID then
		tr.Entity:SetNWInt("price", b)
	else
		Notify(ply, 1, 4, "Must be looking at a Gun Lab or Microwave!")
	end
	return ""
end
AddChatCommand("/price", SetPrice)

function BuyPistol(ply, args)
	if (args == "") then return "" end

	if CfgVars["restrictbuypistol"] ~= 0 and ply:Team() ~= TEAM_GUN and team.NumPlayers(TEAM_GUN) > 0 then
		Notify(ply, 1, 3, "/buypistol is disabled because there are Gun Dealers.")
		return ""
	end

	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	local tr = util.TraceLine(trace)
	if (ply:GetTable().Arrested) then return "" end

	if (args == "deagle") then
		local price = 0
		if ply:Team() == TEAM_GUN then
			price = math.ceil(GetGlobalInt("deaglecost") * 0.88)
		else
			price = GetGlobalInt("deaglecost")
		end
		if not ply:CanAfford(price) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(price * -1)
		Notify(ply, 1, 3, "You bought a deagle for " .. CUR .. tostring(price))
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_deagle.mdl")
		weapon:SetNWString("weaponclass", "weapon_deagle2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (args == "fiveseven") then
		local price = 0
		if ply:Team() == TEAM_GUN then
			price = math.ceil(GetGlobalInt("fivesevencost") * 0.88)
		else
			price = GetGlobalInt("fivesevencost")
		end
		if not ply:CanAfford(price) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(price * -1)
		Notify(ply, 1, 3, "You bought a fiveseven for " .. CUR .. tostring(price))
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_fiveseven.mdl")
		weapon:SetNWString("weaponclass", "weapon_fiveseven2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (args == "glock") then
		local price = 0
		if ply:Team() == TEAM_GUN then
			price = math.ceil(GetGlobalInt("glockcost") * 0.88)
		else
			price = GetGlobalInt("glockcost")
		end
		if not ply:CanAfford(price) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(price * -1)
		Notify(ply, 1, 3, "You bought a glock for " .. CUR .. tostring(price))
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_glock18.mdl")
		weapon:SetNWString("weaponclass", "weapon_glock2")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	elseif (args == "p228") then
		local price = 0
		if ply:Team() == TEAM_GUN then
			price = math.ceil(GetGlobalInt("p228cost") * 0.88)
		else
			price = GetGlobalInt("p228cost")
		end
		if not ply:CanAfford(price) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(price * -1)
		Notify(ply, 1, 3, "You bought a p228 for " .. CUR .. tostring(price) .. "!")
		local weapon = ents.Create("spawned_weapon")
		weapon:SetModel("models/weapons/w_pist_p228.mdl")
		weapon:SetNWString("weaponclass", "weapon_p2282")
		weapon:SetNWString("Owner", "Shared")
		weapon:SetPos(tr.HitPos)
		weapon.nodupe = true
		weapon:Spawn()
	else
		Notify(ply, 1, 3, "That's not an available weapon.")
	end
	return ""
end
AddChatCommand("/buypistol", BuyPistol)

function BuyWeapons(ply, args)
	if (args == "") then return "" end

	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	local tr = util.TraceLine(trace)

	if ply:GetTable().Arrested then return "" end

	if ply:Team() ~= TEAM_GUN then
		Notify(ply, 1, 3, "Must be a Gun Dealer to buy gun shipments!")
		return ""
	end

	if args == "ak47" then
		if not ply:CanAfford(GetGlobalInt("ak47cost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(GetGlobalInt("ak47cost") * -1)
		Notify(ply, 1, 3, "You bought a shipment of ak47s!")
		local crate = ents.Create("spawned_shipment")
		crate:SetContents(args, 10, 4.0)
		crate:SetPos(Vector(tr.HitPos.x, tr.HitPos.y, tr.HitPos.z))
		crate.nodupe = true
		crate:Spawn()
	elseif args == "mp5" then
		if not ply:CanAfford(GetGlobalInt("mp5cost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(GetGlobalInt("mp5cost") * -1)
		Notify(ply, 1, 3, "You bought a shipment of mp5s!")
		local crate = ents.Create("spawned_shipment")
		crate:SetContents(args, 10, 3.0)
		crate:SetPos(Vector(tr.HitPos.x, tr.HitPos.y, tr.HitPos.z))
		crate.nodupe = true
		crate:Spawn()
	elseif args == "m16" then
		if not ply:CanAfford(GetGlobalInt("m16cost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(GetGlobalInt("m16cost") * -1)
		Notify(ply, 1, 3, "You bought a shipment of m16s!")
		local crate = ents.Create("spawned_shipment")
		crate:SetContents(args, 10, 3.0)
		crate:SetPos(Vector(tr.HitPos.x, tr.HitPos.y, tr.HitPos.z))
		crate.nodupe = true
		crate:Spawn()
	elseif args == "mac10" then
		if not ply:CanAfford(GetGlobalInt("mac10cost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(GetGlobalInt("mac10cost") * -1)
		Notify(ply, 1, 3, "You bought a shipment of mac10s!")
		local crate = ents.Create("spawned_shipment")
		crate:SetContents(args, 10, 2.5)
		crate:SetPos(Vector(tr.HitPos.x, tr.HitPos.y, tr.HitPos.z))
		crate.nodupe = true
		crate:Spawn()
	elseif args == "shotgun" then
		if not ply:CanAfford(GetGlobalInt("shotguncost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(GetGlobalInt("shotguncost") * -1)
		Notify(ply, 1, 3, "You bought a shipment of shotguns!")
		local crate = ents.Create("spawned_shipment")
		crate:SetContents(args, 10, 3.3)
		crate:SetPos(Vector(tr.HitPos.x, tr.HitPos.y, tr.HitPos.z))
		crate.nodupe = true
		crate:Spawn()
	elseif args == "sniper" then
		if not ply:CanAfford(GetGlobalInt("snipercost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(GetGlobalInt("snipercost") * -1)
		Notify(ply, 1, 3, "You bought a shipment of snipers!")
		local crate = ents.Create("spawned_shipment")
		crate:SetContents(args, 10, 5.9)
		crate:SetPos(Vector(tr.HitPos.x, tr.HitPos.y, tr.HitPos.z))
		crate.nodupe = true
		crate:Spawn()
	else
		Notify(ply, 1, 3, "That's not an available weapon.")
	end
	return ""
end
AddChatCommand("/buyshipment", BuyWeapons)

function BuyDrugLab(ply)
	if args == "" then return "" end

	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	if ply:GetTable().Arrested then return "" end

	local tr = util.TraceLine(trace)
	if not ply:CanAfford(GetGlobalInt("druglabcost")) then
		Notify(ply, 1, 3, "Can not afford this!")
		return ""
	end
	if ply:GetNWInt("maxDrug") == CfgVars["maxdruglabs"] then
		Notify(ply, 1, 3, "Max Drug Labs Reached!")
		return ""
	end
	ply:AddMoney(GetGlobalInt("druglabcost") * -1)
	Notify(ply, 1, 3, "You bought a Drug Lab")
	local druglab = ents.Create("drug_lab")
	druglab:SetNWEntity("owning_ent", ply)
	druglab:SetNWString("Owner", ply:Nick())
	druglab:SetPos(tr.HitPos)
	druglab.SID = ply.SID
	druglab.onlyremover = true
	druglab:Spawn()
	return ""
end
AddChatCommand("/buydruglab", BuyDrugLab)

function BuyMicrowave(ply)
	if args == "" then return "" end
	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	if ply:GetTable().Arrested then return "" end
	local tr = util.TraceLine(trace)

	if not ply:CanAfford(GetGlobalInt("microwavecost")) then
		Notify(ply, 1, 3, "Can not afford this!")
		return ""
	end

	if ply:GetNWInt("maxmicrowaves") == CfgVars["maxmicrowaves"] then
		Notify(ply, 1, 3, "Max Microwaves reached!")
		return ""
	end

	if ply:Team() == TEAM_COOK then
		ply:AddMoney(GetGlobalInt("microwavecost") * -1)
		Notify(ply, 1, 3, "You bought a Microwave")
		local microwave = ents.Create("microwave")
		microwave:SetNWInt("price", GetGlobalInt("microwavefoodcost"))
		microwave:SetNWEntity("owning_ent", ply)
		microwave:SetNWString("Owner", ply:Nick())
		microwave:SetNWBool("microwave", true)
		microwave:SetPos(tr.HitPos)
		microwave.nodupe = true
		microwave:Spawn()
		microwave.SID = ply.SID
		return ""
	else
		Notify(ply, 1, 3, "You must be the Cook to buy this.")
	end
	return ""
end
AddChatCommand("/buymicrowave", BuyMicrowave)

function BuyGunlab(ply)
	if args == "" then return "" end
	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	if ply:GetTable().Arrested then return "" end
	local tr = util.TraceLine(trace)

	if not ply:CanAfford(GetGlobalInt("gunlabcost")) then
		Notify(ply, 1, 3, "Can not afford this!")
		return ""
	end
	if ply:GetNWInt("maxgunlabs") == CfgVars["maxgunlabs"] then
		Notify(ply, 1, 3, "Max Gun Labs Reached!")
		return ""
	end
	if ply:Team() == TEAM_GUN then
		ply:AddMoney(GetGlobalInt("gunlabcost") * -1)
		Notify(ply, 1, 3, "You bought a Gun Lab")
		local gunlab = ents.Create("gunlab")
		gunlab:SetNWEntity("owning_ent", ply)
		gunlab:SetNWString("Owner", ply:Nick())
		gunlab:SetNWInt("price", GetGlobalInt("p228cost"))
		gunlab:SetNWBool("gunlab", true)
		gunlab:SetPos(tr.HitPos)
		gunlab.nodupe = true
		gunlab:Spawn()
		gunlab.SID = ply.SID
		return ""
	else
		Notify(ply, 1, 3, "Must be the Gun Dealer!")
	end
	return ""
end
AddChatCommand("/buygunlab", BuyGunlab)

function BuyMoneyPrinter(ply, args)
	if ply:GetTable().Arrested then return "" end
	local trace = {}
	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply
	local tr = util.TraceLine(trace)

	if not ply:CanAfford(GetGlobalInt("mprintercost")) then
		Notify(ply, 1, 3, "Cannot afford this")
		return ""
	end

	if ply:GetNWInt("maxmprinters") >= CfgVars["maxmprinters"] then
		Notify(ply, 1, 3, "Max Money Printers Reached!")
		return ""
	end

	ply:AddMoney(GetGlobalInt("mprintercost") * -1)
	Notify(ply, 1, 3, "You bought a Money Printer for " .. CUR .. GetGlobalInt("mprintercost") .. "!")
	local moneyprinter = ents.Create("money_printer")
	moneyprinter:SetNWEntity("owning_ent", ply)
	moneyprinter:SetNWString("Owner", "Shared") -- So people can run off with them!
	moneyprinter:SetPos(tr.HitPos)
	moneyprinter.onlyremover = true
	moneyprinter.SID = ply.SID
	moneyprinter:Spawn()
	return ""
end
AddChatCommand("/buymoneyprinter", BuyMoneyPrinter)

function BuyAmmo(ply, args)
	if args == "" then return "" end

	if ply:GetTable().Arrested then return "" end

	if args == "rifle" then
		if not ply:CanAfford(GetGlobalInt("ammoriflecost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:GiveAmmo(80, "smg1")
		ply:AddMoney(GetGlobalInt("ammoriflecost") * -1)
	elseif args == "shotgun" then
		if not ply:CanAfford(GetGlobalInt("ammoshotguncost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:GiveAmmo(50, "buckshot")
		ply:AddMoney(GetGlobalInt("ammoshotguncost") * -1)
	elseif args == "pistol" then
		if not ply:CanAfford(GetGlobalInt("ammopistolcost")) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:GiveAmmo(50, "pistol")
		ply:AddMoney(GetGlobalInt("ammopistolcost") * -1)
	else
		Notify(ply, 1, 3, "That ammo is not available.")
	end
	return ""
end
AddChatCommand("/buyammo", BuyAmmo)

function BuyHealth(ply)
	if not ply:CanAfford(GetGlobalInt("healthcost")) then
		Notify(ply, 1, 3, "Can not afford this!")
		return ""
	end
	if ply:Team() ~= TEAM_MEDIC and team.NumPlayers(TEAM_MEDIC) > 0 then
		Notify(ply, 1, 3, "/buyhealth is disabled because there are Medics.")
		return ""
	else
		ply:AddMoney(GetGlobalInt("healthcost") * -1)
		Notify(ply, 1, 3, "You bought health")
		ply:SetHealth(100)
		return ""
	end
	return ""
end
AddChatCommand("/buyhealth", BuyHealth)

function BuyFood(ply, args)
	if args == "" then return "" end
	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	local tr = util.TraceLine(trace)

	if GetGlobalInt("hungermod") == 0 then
		Notify(ply, 1, 3, "/buyfood is disabled unless Hunger Mod is enabled.")
		return ""
	end

	if ply:Team() ~= TEAM_COOK and team.NumPlayers(TEAM_COOK) > 0 then
		Notify(ply, 1, 3, "/buyfood is disabled because there are cooks.")
		return ""
	end

	if args == "melon" then
		if (not ply:CanAfford(CfgVars["foodcost"])) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end
		ply:AddMoney(CfgVars["foodcost"] * -1)
		Notify(ply, 1, 3, "You bought a Melon for " .. CUR .. tostring(CfgVars["foodcost"]))
		local food = ents.Create("melon")
		food:SetModel("models/props_junk/watermelon01.mdl")
		food:SetNWString("Owner", "Shared")
		food:SetPos(tr.HitPos)
		food.nodupe = true
		food:Spawn()
	else
		Notify(ply, 1, 3, "That Food Is not available.")
	end
	return ""
end
AddChatCommand("/buyfood", BuyFood)

function JailPos(ply)
	-- Admin or Chief can set the Jail Position
	if ply:HasPriv(ADMIN) or ply:Team() == TEAM_CHIEF then
		DB.StoreJailPos(ply)
	else
		Notify(ply, 1, 4,  "Chief or Admin Only!")
		return ""
	end
	return ""
end
AddChatCommand("/jailpos", JailPos)

function MakeGangster(ply)
	ply:ChangeTeam(TEAM_GANG)
	return ""
end
AddChatCommand("/gangster", MakeGangster)

function MakeMobBoss(ply)
	ply:ChangeTeam(TEAM_MOB)
	return ""
end
AddChatCommand("/mobboss", MakeMobBoss)

function CreateAgenda(ply, args)
	if ply:Team() == TEAM_MOB then
		for k, v in pairs(player.GetAll()) do
			local t = v:Team()
			if t == TEAM_GANG or t == TEAM_MOB then
				v:PrintMessage(HUD_PRINTTALK, "Mob Boss Updated Agenda")
				local ftext = string.gsub(args, "//", "\n")
				v:SetNWString("agenda", ftext)
			else
				Notify(ply, 1, 4, "The Mob Boss Updated the Agenda")
			end
		end
	else
		Notify(ply, 1, 4, "Must be a Mob Boss to use this command.")
	end
	return ""
end
AddChatCommand("/agenda", CreateAgenda)

timer.Create("start", 1, 0, StartShower)
timer.Create("stormControl", 1, 0, ControlStorm)
timer.Create("start2", 1, 0, SpawnZombie)
timer.Create("zombieControl", 1, 0, ControlZombie)
timer.Stop("start")
timer.Stop("stormControl")
timer.Stop("start2")
timer.Stop("zombieControl")

function GetHelp(ply, args)
	umsg.Start("ToggleHelp", ply)
	umsg.End()
	return ""
end
AddChatCommand("/help", GetHelp)

function WriteLetter(ply, args)
	if (CfgVars["letters"] == 0) then
		Notify(ply, 1, 4, "Letter writing disabled")
		return ""
	end

	if (ply:GetNWInt("maxletters") >= 4) then
		Notify(ply, 1, 4, "Max Letters Reached!")
		return ""
	end

	if (CurTime() - ply:GetTable().LastLetterMade < 3) then
		Notify(ply, 1, 4, "Wait another " .. math.ceil(3 - (CurTime() - ply:GetTable().LastLetterMade)) .. " seconds to make a letter")
		return ""
	end

	ply:GetTable().LastLetterMade = CurTime()

	local ftext = string.gsub(args, "//", "\n")

	local tr = { }
	tr.start = ply:EyePos()
	tr.endpos = ply:EyePos() + 95 * ply:GetAimVector()
	tr.filter = ply
	local trace = util.TraceLine(tr)

	local letter = ents.Create("letter")
	letter:SetModel("models/props_c17/paper01.mdl")
	letter:SetNWString("Owner", "Shared")
	letter:SetPos(trace.HitPos)
	letter.nodupe = true
	letter:Spawn()

	letter:GetTable().Letter = true
	letter:SetNWInt("type", 1)
	letter:SetNWString("content", ftext)
	letter.SID = ply.SID

	PrintMessageAll(2, ply:Nick() .. " created a letter.")
	ply:PrintMessage(2, "CREATED LETTER:\n" .. args)
	local ply = letter:GetNWEntity("owning_ent")
	ply:SetNWInt("maxletters",ply:GetNWInt("maxletters") + 1)

	return ""
end
AddChatCommand("/write", WriteLetter)

function TypeLetter(ply, args)
	if (CfgVars["letters"] == 0) then
		Notify(ply, 1, 4, "Letter typing disabled")
		return ""
	end

	if (ply:GetNWInt("maxletters") >= 4) then
		Notify(ply, 1, 4, "Max Letters Reached!")
		return ""
	end

	if (CurTime() - ply:GetTable().LastLetterMade < 3) then
		Notify(ply, 1, 4, "Wait another " .. math.ceil(3 - (CurTime() - ply:GetTable().LastLetterMade)) .. " seconds to make a letter")
		return ""
	end

	ply:GetTable().LastLetterMade = CurTime()

	local ftext = string.gsub(args, "//", "\n")

	local tr = { }
	tr.start = ply:EyePos()
	tr.endpos = ply:EyePos() + 95 * ply:GetAimVector()
	tr.filter = ply
	local trace = util.TraceLine(tr)

	local letter = ents.Create("letter")
	letter:SetModel("models/props_c17/paper01.mdl")
	letter:SetNWString("Owner", "Shared")
	letter:SetPos(trace.HitPos)
	letter.nodupe = true
	letter:Spawn()

	letter:GetTable().Letter = true
	letter:SetNWInt("type", 2)
	letter:SetNWString("content", ftext)
	letter.SID = ply.SID

	PrintMessageAll(2, ply:Nick() .. " created a letter.")
	ply:PrintMessage(2, "CREATED LETTER:\n" .. args)
	local ply = letter:GetNWEntity("owning_ent")
	ply:SetNWInt("maxletters",ply:GetNWInt("maxletters") + 1)

	return ""
end
AddChatCommand("/type", TypeLetter)

function ChangeJob(ply, args)
	if (args == "") then return "" end

	NotifyAll(2, 4, ply:Nick() .. " has set job to " .. args .. "!")
	ply:UpdateJob(args)
	return ""
end
AddChatCommand("/job", ChangeJob)

function GroupMsg(ply, args)
	local t = ply:Team()
	local audience = {}

	if t == TEAM_POLICE or t == TEAM_CHIEF or t == TEAM_MAYOR then
		for k, v in pairs(player.GetAll()) do
			local vt = v:Team()
			if vt == TEAM_POLICE or vt == TEAM_CHIEF or vt == TEAM_MAYOR then table.insert(audience, v) end
		end
	elseif t == TEAM_MOB or t == TEAM_GANG then
		for k, v in pairs(player.GetAll()) do
			local vt = v:Team()
			if vt == TEAM_MOB or vt == TEAM_GANG then table.insert(audience, v) end
		end
	end

	for k, v in pairs(audience) do
		v:PrintMessage(2, ply:Nick() .. ": (GROUP) " .. args)
		v:PrintMessage(3, ply:Nick() .. ": (GROUP) " .. args)
	end
	return ""
end
AddChatCommand("/g", GroupMsg)

function PM(ply, args)
	local namepos = string.find(args, " ")
	if (not namepos) then return "" end

	local name = string.sub(args, 1, namepos - 1)
	local msg = string.sub(args, namepos + 1)

	target = FindPlayer(name)

	if (target) then
		target:PrintMessage(2, ply:Nick() .. ": (PM) " .. msg)
		target:PrintMessage(3, ply:Nick() .. ": (PM) " .. msg)

		ply:PrintMessage(2, ply:Nick() .. ": (PM) " .. msg)
		ply:PrintMessage(3, ply:Nick() .. ": (PM) " .. msg)
	else
		Notify(ply, 1, 3, "Could not find player: " .. name)
	end

	return ""
end
AddChatCommand("/pm", PM)

function Whisper(ply, args)
	TalkToRange("(WHISPER)" .. ply:Nick() .. ": " .. args, ply:EyePos(), 90)
	return ""
end
AddChatCommand("/w", Whisper)

function Yell(ply, args)
	TalkToRange("(YELL)" .. ply:Nick() .. ": " .. args, ply:EyePos(), 550)
	return ""
end
AddChatCommand("/y", Yell)

function OOC(ply, args)
	if (CfgVars["ooc"] == 0) then
		Notify(ply, 1, 3, "OOC is disabled")
		return ""
	end

	return "(OOC) " .. args
end
AddChatCommand("//", OOC, true)
AddChatCommand("/a", OOC, true)
AddChatCommand("/ooc", OOC, true)

function GiveMoney(ply, args)
	if (args == "") then return "" end

	local trace = ply:GetEyeTrace()

	if (ValidEntity(trace.Entity) and trace.Entity:IsPlayer() and trace.Entity:GetPos():Distance(ply:GetPos()) < 150) then
		local amount = math.floor(tonumber(args))

		if (amount <= 1) then
			Notify(ply, 1, 4, "Invalid amount of money! Must be at least " .. CUR .. "2!")
			return
		end

		if (not ply:CanAfford(amount)) then
			Notify(ply, 1, 3, "Can not afford this!")
			return ""
		end

		DB.PayPlayer(ply, trace.Entity, amount)

		Notify(trace.Entity, 0, 4, ply:Nick() .. " has given you " .. CUR .. amount .. "!")
		Notify(ply, 0, 4, "Gave " .. trace.Entity:Nick() .. " " .. CUR .. amount .. "!")
	else
		Notify(ply, 1, 3, "Must be looking at and be within distance of another player!")
	end
	return ""
end
AddChatCommand("/give", GiveMoney)

function DropMoney(ply, args)
	if (args == "") then return "" end

	local amount = math.floor(tonumber(args))

	if (amount <= 1) then
		Notify(ply, 1, 4, "Invalid amount of money! Must be at least " .. CUR .. "2!")
		return ""
	end

	if (not ply:CanAfford(amount)) then
		Notify(ply, 1, 3, "Can not afford this!")
		return ""
	end

	ply:AddMoney(amount * -1)

	local trace = { }

	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 85
	trace.filter = ply

	local tr = util.TraceLine(trace)
	local moneybag = ents.Create("prop_physics")
	moneybag:SetModel("models/props/cs_assault/money.mdl")
	moneybag:SetNWString("Owner", "Shared")
	moneybag:SetPos(tr.HitPos)
	moneybag.nodupe = true
	moneybag:Spawn()
	moneybag:GetTable().MoneyBag = true
	moneybag:GetTable().Amount = amount

	return ""
end
AddChatCommand("/dropmoney", DropMoney)
AddChatCommand("/moneydrop", DropMoney)

function SetDoorTitle(ply, args)

	local trace = ply:GetEyeTrace()

	if (ValidEntity(trace.Entity) and trace.Entity:IsOwnable() and ply:GetPos():Distance(trace.Entity:GetPos()) < 110) then
		if (trace.Entity:OwnedBy(ply)) then
			trace.Entity:SetNWString("title", args)
		else
			Notify(ply, 1, 3, "You don't own this!")
		end
	end

	return ""
end
AddChatCommand("/title", SetDoorTitle)

function RemoveDoorOwner(ply, args)
	local trace = ply:GetEyeTrace()

	if (ValidEntity(trace.Entity) and trace.Entity:IsOwnable() and ply:GetPos():Distance(trace.Entity:GetPos()) < 110) then
		target = FindPlayer(args)

		if (target) then
			if (trace.Entity:OwnedBy(ply)) then
				if (trace.Entity:AllowedToOwn(target)) then
					trace.Entity:RemoveAllowed(target)
				end

				if (trace.Entity:OwnedBy(target)) then
					trace.Entity:RemoveOwner(target)
				end
			else
				Notify(ply, 1, 3, "You don't own this!")
			end
		else
			Notify(ply, 1, 3, "Could not find player: " .. args)
		end
	end
	return ""
end
AddChatCommand("/removeowner", RemoveDoorOwner)
AddChatCommand("/ro", RemoveDoorOwner)

function AddDoorOwner(ply, args)
	local trace = ply:GetEyeTrace()

	if (ValidEntity(trace.Entity) and trace.Entity:IsOwnable() and ply:GetPos():Distance(trace.Entity:GetPos()) < 110) then
		target = FindPlayer(args)
		if (target) then
			if (trace.Entity:OwnedBy(ply)) then
				if (not trace.Entity:OwnedBy(target) and not trace.Entity:AllowedToOwn(target)) then
					trace.Entity:AddAllowed(target)
				else
					Notify(ply, 1, 3, "Player already owns this door, or is allowed to own!")
				end
			else
				Notify(ply, 1, 3, "You don't own this!")
			end
		else
			Notify(ply, 1, 3, "Could not find player: " .. args)
		end
	end
	return ""
end
AddChatCommand("/addowner", AddDoorOwner)
AddChatCommand("/ao", AddDoorOwner)

function Demote(ply, args)
	local p = FindPlayer(args)
	if p then
		if (CurTime() - ply:GetTable().LastVoteCop < 80) then
			Notify(ply, 1, 4, "Please wait another " .. math.ceil(80 - (CurTime() - ply:GetTable().LastVoteCop)) .. " seconds before demoting.")
			return ""
		end
		if (p:Team() == TEAM_CITIZEN) then
			Notify(ply, 1, 4,  p:Nick() .." is a Citizen - can't be demoted any further!")
		else
			NotifyAll(1, 4, ply:Nick() .. " has started a vote for the demotion of " .. p:Nick())
			vote:Create(p:Nick() .. ":\n Demotion Nominee", p:EntIndex() .. "votecop", p, 12, FinishDemote)
			ply:GetTable().LastVoteCop = CurTime()
			VoteCopOn = true
			Notify(ply, 1, 3, "Demotion Vote Started")
		end
		return ""
	else
		Notify(ply, 1, 3, "Player does not exist.")
		return ""
	end
end
AddChatCommand("/demote", Demote)

function FinishDemote(choice, v)
	VoteCopOn = false

	if (choice == 1) then
		v:TeamBan()
		if v:Alive() then
			v:ChangeTeam(TEAM_CITIZEN)
		else
			v.demotedWhileDead = true
		end

		NotifyAll(1, 4, v:Nick() .. " has been Demoted!")
	else
		NotifyAll(1, 4, v:Nick() .. " has not been Demoted!")
	end
end

function FinishVoteMayor(choice, ply)
	VoteCopOn = false

	if (choice == 1) then
		ply:ChangeTeam(TEAM_MAYOR)
	else
		NotifyAll(1, 4, ply:Nick() .. " has not been made Mayor!")
	end
end

function FinishVoteCop(choice, ply)
	VoteCopOn = false

	if (choice == 1) then
		ply:ChangeTeam(TEAM_POLICE)
	else
		NotifyAll(1, 4, ply:Nick() .. " has not been made Civil Protection!")
	end
end

function DoVoteMayor(ply, args)
	if (CfgVars["mayorvoting"] == 0) then
		Notify(ply, 1, 4,  "Mayor voting is disabled!")
		return ""
	end

	if not ply:ChangeAllowed(TEAM_MAYOR) then
		Notify(ply, 1, 4, "You were demoted! Please wait a while before taking your old job back")
		return ""
	end

	if (CurTime() - ply:GetTable().LastVoteCop < 80) then
		Notify(ply, 1, 4, "Wait another " .. math.ceil(80 - (CurTime() - ply:GetTable().LastVoteCop)) .. " seconds to votemayor!")
		return ""
	end

	if (VoteCopOn) then
		Notify(ply, 1, 4,  "There is already a vote!")
		return ""
	end

	if CfgVars["cptomayoronly"] == 1 then
		if ply:Team() ~= TEAM_POLICE and ply:Team() ~= TEAM_CHIEF then
			Notify(ply, 1, 4,  "You have to be in the Civil Protection!")
			return ""
		end
	end

	if ply:Team() == TEAM_MAYOR then
		Notify(ply, 1, 4,  "You're already Mayor!")
		return ""
	end

	if team.NumPlayers(TEAM_MAYOR) >= CfgVars["maxmayor"] then
		Notify(ply, 1, 4,  "Max number of Mayors: " .. CfgVars["maxmayor"])
		return ""
	end

	vote:Create(ply:Nick() .. ":\nwants to be Mayor", ply:EntIndex() .. "votecop", ply, 12, FinishVoteMayor)
	ply:GetTable().LastVoteCop = CurTime()
	VoteCopOn = true

	return ""
end
AddChatCommand("/votemayor", DoVoteMayor)

function DoVoteCop(ply, args)

	if (CfgVars["cpvoting"] == 0) then
		Notify(ply, 1, 4,  "Cop voting is disabled!")
		return ""
	end

	if not ply:ChangeAllowed(TEAM_POLICE) then
		Notify(ply, 1, 4, "You were demoted! Please wait a while before taking your old job back")
		return ""
	end

	if (CurTime() - ply:GetTable().LastVoteCop < 60) then
		Notify(ply, 1, 4, "Wait another " .. math.ceil(60 - (CurTime() - ply:GetTable().LastVoteCop)) .. " seconds to vote for Cop!")
		return ""
	end

	if (VoteCopOn) then
		Notify(ply, 1, 4,  "There is already a vote for Cop!")
		return ""
	end

	if ply:Team() == TEAM_POLICE then
		Notify(ply, 1, 4,  "You're already in the Civil Protection!")
		return ""
	end

	if (team.NumPlayers(TEAM_POLICE) >= CfgVars["maxcps"]) then
		Notify(ply, 1, 4,  "Max number of CP's are: " .. CfgVars["maxcps"])
		return ""
	end

	vote:Create(ply:Nick() .. ":\nwants to be a Cop", ply:EntIndex() .. "votecop", ply, 12, FinishVoteCop)
	ply:GetTable().LastVoteCop = CurTime()
	VoteCopOn = true

	return ""
end
AddChatCommand("/votecop", DoVoteCop)

function MakeMayor(ply, args)
	if ply:HasPriv(ADMIN) or ply:HasPriv(MAYOR) then
		if VoteCopOn then
			Notify(ply, 1, 4,  "Please wait for the vote to finish first.")
		else
			ply:ChangeTeam(TEAM_MAYOR)
		end
	else
		Notify(ply, 1, 4, "You Must be on the Mayor List or Admin!")
	end
	return ""
end
AddChatCommand("/mayor", MakeMayor)

function MakeCitizen(ply, args)
	ply:ChangeTeam(TEAM_CITIZEN)
	return ""
end
AddChatCommand("/citizen", MakeCitizen)

function MakeCP(ply, args)
	if ply:HasPriv(CP) or ply:HasPriv(ADMIN) or ply:HasPriv(MAYOR) then
		if VoteCopOn then
			Notify(ply, 1, 4,  "Please wait for the vote to finish first.")
		else
			ply:ChangeTeam(TEAM_POLICE)
		end
	else
		Notify(ply, 1, 4, "You have to be on the CP or Mayor List or Admin!")
	end
	return ""
end
AddChatCommand("/cp", MakeCP)

function MakeDealer(ply, args)
	ply:ChangeTeam(TEAM_GUN)
	return ""
end
AddChatCommand("/gundealer", MakeDealer)

function MakePDChief(ply, args)
	ply:ChangeTeam(TEAM_CHIEF)
	return ""
end
AddChatCommand("/chief", MakePDChief)

function MakeMedic(ply, args)
	ply:ChangeTeam(TEAM_MEDIC)
	return ""
end
AddChatCommand("/medic", MakeMedic)

function MakeCook(ply, args)
	ply:ChangeTeam(TEAM_COOK)
	return ""
end
AddChatCommand("/cook", MakeCook)

function CombineRadio(ply, args)
	local t = ply:Team()
	if (t == TEAM_POLICE or t == TEAM_MAYOR or t == TEAM_CHIEF) then
		for k, v in pairs(player.GetAll()) do
			local vt = v:Team()
			if (vt == TEAM_POLICE or vt == TEAM_MAYOR or vt == TEAM_CHIEF) then
				v:ChatPrint(ply:Nick() .. ": (RADIO) " .. args)
				v:PrintMessage(2, ply:Nick() .. ": (RADIO) " .. args)
			end
		end
	end
	return ""
end
AddChatCommand("/r", CombineRadio)

function CombineRequest(ply, args)
	local t = ply:Team()
	if t ~= TEAM_POLICE and t ~= TEAM_CHIEF then
		ply:ChatPrint(ply:Nick() .. ": (REQUEST!) " .. args)
		ply:PrintMessage(2, ply:Nick() .. ": (REQUEST!) " .. args)
	end

	for k, v in pairs(player.GetAll()) do
		if v:Team() == TEAM_POLICE or v:Team() == TEAM_CHIEF then
			v:ChatPrint(ply:Nick() .. ": (REQUEST!) " .. args)
			v:PrintMessage(2, ply:Nick() .. ": (REQUEST!) " .. args)
		end
	end
	return ""
end
AddChatCommand("/cr", CombineRequest)

function FoodHeal(ply)
	if (GetGlobalInt("hungermod") == 0) then
		ply:SetHealth(ply:Health() + (100 - ply:Health()))
	else
		ply:SetNWInt("Energy", math.Clamp(ply:GetNWInt("Energy") + 100, 0, 100))
		umsg.Start("AteFoodIcon")
		umsg.End()
	end
	return ""
end

function Lockdown(ply)
	if (GetGlobalInt("lstat") ~= 1) then
		if ply:Team() == TEAM_MAYOR or ply:HasPriv(ADMIN) then
			for k,v in pairs(player.GetAll()) do
				v:ConCommand("play npc/overwatch/cityvoice/f_confirmcivilstatus_1_spkr.wav\n")
			end
			SetGlobalInt("lstat", 1)
			PrintMessageAll(HUD_PRINTTALK , "Lockdown In Progress, Please Return to your Homes.")
			NotifyAll(4, 3, ply:Nick() .. " Has Initiated a Lockdown, Please Return to your Homes.")
		end
	end
	return ""
end
concommand.Add("rp_lockdown", Lockdown)
AddChatCommand("/lockdown", Lockdown)

function UnLockdown(ply)
	if (GetGlobalInt("lstat") == 1 and GetGlobalInt("ulstat") == 0) then
		if ply:Team() == TEAM_MAYOR or ply:HasPriv(ADMIN) then
			PrintMessageAll(HUD_PRINTTALK , "Lockdown has ended.")
			NotifyAll(4, 3, ply:Nick() .. " Has ended the Lockdown.")
			SetGlobalInt("ulstat", 1)
			timer.Create("spamlock", 20, 1, WaitLock, "")
		end
	end
	return ""
end
concommand.Add("rp_unlockdown", UnLockdown)
AddChatCommand("/unlockdown", UnLockdown)

function WaitLock()
	SetGlobalInt("ulstat", 0)
	SetGlobalInt("lstat", 0)
	timer.Destroy("spamlock")
end

function SetCPBudget(amount)
	file.Write("DarkRP/temp/budgets/cpbudget.txt", math.floor(amount))
end

function RefreshGlobals()
	if (CfgVars["refreshglobals"] ~= 1) then
		SetGlobalInt("ak47cost", 2450)
		SetGlobalInt("mp5cost", 2200)
		SetGlobalInt("m16cost", 2450)
		SetGlobalInt("mac10cost", 2150)
		SetGlobalInt("shotguncost", 1750)
		SetGlobalInt("snipercost", 3750)
		SetGlobalInt("deaglecost", 215)
		SetGlobalInt("fivesevencost", 205)
		SetGlobalInt("glockcost", 160)
		SetGlobalInt("p228cost", 185)
		SetGlobalInt("druglabcost", 400)
		SetGlobalInt("gunlabcost", 500)
		SetGlobalInt("mprintercost", 1000)
		SetGlobalInt("mprintamount", 250)
		SetGlobalInt("microwavecost", 400)
		SetGlobalInt("drugpayamount", 15)
		SetGlobalInt("ammopistolcost", 30)
		SetGlobalInt("ammoriflecost", 60)
		SetGlobalInt("ammoshotguncost", 70)
		SetGlobalInt("healthcost", 60)
		SetGlobalInt("jailtimer", 120)
		SetGlobalInt("microwavefoodcost", 30)
		SetGlobalInt("mayorsetsalary", 120)
		SetGlobalInt("maxcopsalary", 100)
		SetGlobalInt("maxdrugfood", 2)
		SetGlobalInt("npckillpay", 10)
		SetGlobalInt("nametag", 1)
		SetGlobalInt("jobtag", 1)
		SetGlobalInt("globalshow", 0)
		SetGlobalInt("deathnotice", 1)
	end
	CfgVars["refreshglobals"] = 1
	timer.Simple(30, refwait)
end

function VerifyGlobals(ply)
	if (ply:EntIndex() ~= 0 and not ply:HasPriv(ADMIN)) then
		ply:PrintMessage(2, "Must Be an admin To Refresh Variables")
		return
	else
		local nick = ""
		if (ply:EntIndex() == 0) then
			nick = "Console"
		else
			nick = ply:Nick()
		end
		NotifyAll(0, 6, nick .. " refreshed the globals!")
		RefreshGlobals()
	end
end
concommand.Add("refresh_int", VerifyGlobals)

function refwait()
	CfgVars["refreshglobals"] = 0
end

function GM:PhysgunPickup(ply, ent)
	if (ent:IsPlayer() or ent:IsDoor()) then return false end

	local class = ent:GetClass()

	if ply:HasPriv(ADMIN) then return true end

	if (class ~= "func_physbox" and class ~= "prop_physics" and class ~= "prop_physics_multiplayer" and
		class ~= "prop_vehicle_prisoner_pod") then
		return false
	end
	return true
end

function GM:PlayerSpawnProp(ply, model)
	if (not self.BaseClass:PlayerSpawnProp(ply, model)) then return false end

	local allowed = false

	if ply:GetTable().Arrested then return false end

	-- Banned props take precedence over allowed props
	if (CfgVars["banprops"] == 1) then
		for k, v in pairs(BannedProps) do
			if (v == model) then return false end
		end
	end

	-- If prop spawning is enabled or the user has admin or prop privileges
	if CfgVars["propspawning"] == 1 or ply:HasPriv(ADMIN) or ply:HasPriv(PROP) then
		-- If we are specifically allowing certain props, if it's not in the list, allowed will remain false
		if CfgVars["allowedprops"] == 1 then
			for k, v in pairs(AllowedProps) do
				if (v == model) then allowed = true end
			end
		else
			-- allowedprops is not enabled, so assume that if it wasn't banned above, it's allowed
			allowed = true
		end
	end

	if (allowed) then
		if (CfgVars["proppaying"] == 1) then
			if (ply:CanAfford(CfgVars["propcost"])) then
				Notify(ply, 1, 4, "Deducted " .. CUR .. CfgVars["propcost"])
				ply:AddMoney(-CfgVars["propcost"])
				return true
			else
				Notify(ply, 1, 4, "Need " .. CUR .. CfgVars["propcost"])
				return false
			end
		else
			return true
		end
	else
		return false
	end
end

function GM:PlayerSpawnSENT(ply, model)
	return self.BaseClass:PlayerSpawnSENT(ply, model) and not ply:GetTable().Arrested
end

function GM:PlayerSpawnSWEP(ply, model)
	return self.BaseClass:PlayerSpawnSWEP(ply, model) and not ply:GetTable().Arrested
end

function GM:PlayerSpawnEffect(ply, model)
	return self.BaseClass:PlayerSpawnEffect(ply, model) and not ply:GetTable().Arrested
end

function GM:PlayerSpawnVehicle(ply, model)
	return self.BaseClass:PlayerSpawnVehicle(ply, model) and not ply:GetTable().Arrested
end

function GM:PlayerSpawnNPC(ply, model)
	return self.BaseClass:PlayerSpawnNPC(ply, model) and not ply:GetTable().Arrested
end

function GM:PlayerSpawnRagdoll(ply, model)
	return self.BaseClass:PlayerSpawnRagdoll(ply, model) and not ply:GetTable().Arrested
end

function GM:PlayerSpawnedProp(ply, model, ent)
	self.BaseClass:PlayerSpawnedProp(ply, model, ent)
	ent.SID = ply.SID
end

function GM:PlayerSpawnedSWEP(ply, model, ent)
	self.BaseClass:PlayerSpawnedSWEP(ply, model, ent)
	ent.SID = ply.SID
end

function GM:PlayerSpawnedRagdoll(ply, model, ent)
	self.BaseClass:PlayerSpawnedRagdoll(ply, model, ent)
	ent.SID = ply.SID
end

function GM:SetupMove(ply, move)
	if ply == nil or not ply:Alive() then
		return
	end

	if ply:Crouching() then
		move:SetMaxClientSpeed(CfgVars["cspd"])
		return
	end

	if ply:GetTable().Arrested then
		move:SetMaxClientSpeed(CfgVars["aspd"])
		return
	end

	if ply:KeyDown(IN_SPEED) then
		local t = ply:Team()
		if ply:HasPriv(ADMIN) or t == TEAM_POLICE or ply:Team() == TEAM_CHIEF then
			local faster = CfgVars["rspd"] + 8
			move:SetMaxClientSpeed(faster)
		else
			move:SetMaxClientSpeed(CfgVars["rspd"])
			return
		end
	elseif ply:GetVelocity():Length() > 10 then
		move:SetMaxClientSpeed(CfgVars["wspd"])
		return
	end
end

function GM:ShowSpare1(ply)
	umsg.Start("ToggleClicker", ply)
	umsg.End()
end

function GM:ShowSpare2(ply)
	local trace = ply:GetEyeTrace()

	if (ValidEntity(trace.Entity) and trace.Entity:IsOwnable() and ply:GetPos():Distance(trace.Entity:GetPos()) < 115) then

		if (trace.Entity:OwnedBy(ply)) then
			Notify(ply, 1, 4, "Sold for " .. CUR .. math.floor(((CfgVars["doorcost"] * 0.66666666666666)+0.5)) .. "!")
			trace.Entity:Fire("unlock", "", 0)
			trace.Entity:UnOwn(ply)
			ply:GetTable().Ownedz[trace.Entity:EntIndex()] = nil
			ply:GetTable().OwnedNumz = ply:GetTable().OwnedNumz - 1
			ply:AddMoney(math.floor(((CfgVars["doorcost"] * 0.66666666666666)+0.5)))
		else
			if (trace.Entity:IsOwned() and not trace.Entity:AllowedToOwn(ply)) then
				Notify(ply, 1, 3, "Already owned")
				return
			end
			if (trace.Entity:GetClass() == "prop_vehicle_jeep" or trace.Entity:GetClass() == "prop_vehicle_airboat") then
				if (not ply:CanAfford(CfgVars["vehiclecost"])) then
					Notify(ply, 1, 4, "You can not afford this vehicle!")
					return
				end
			else
				if (not ply:CanAfford(CfgVars["doorcost"])) then
					Notify(ply, 1, 4, "You can not afford this door!")
					return
				end
			end

			if (trace.Entity:GetClass() == "prop_vehicle_jeep" or trace.Entity:GetClass() == "prop_vehicle_airboat") then
				ply:AddMoney(CfgVars["vehiclecost"] * -1)
				Notify(ply, 1, 4, "You've owned this vehicle for " .. CUR .. math.floor(CfgVars["vehiclecost"]) .. "!")
			else
				ply:AddMoney(CfgVars["doorcost"] * -1)
				Notify(ply, 1, 4, "You've owned this door for " .. CUR .. math.floor(CfgVars["doorcost"]) .. "!")
			end
			trace.Entity:Own(ply)

			if (ply:GetTable().OwnedNumz == 0) then
				timer.Create(ply:SteamID() .. "propertytax", 270, 0, ply.DoPropertyTax, ply)
			end

			ply:GetTable().OwnedNumz = ply:GetTable().OwnedNumz + 1

			ply:GetTable().Ownedz[trace.Entity:EntIndex()] = trace.Entity
		end
	end
end

function GM:OnNPCKilled(victim, ent, weapon)
	-- If something killed the npc
	if ent then
		if ent:IsVehicle() and ent:GetDriver():IsPlayer() then ent = ent:GetDriver() end

		-- if it wasn't a player directly, find out who owns the prop that did the killing
		if not ent:IsPlayer() then
			ent = FindPlayerBySID(ent.SID)
		end

		-- if we know by now who killed the NPC, pay them.
		if ent and CfgVars["npckillpay"] > 0 then
			ent:AddMoney(CfgVars["npckillpay"])
			Notify(ent, 1, 3, CUR .. CfgVars["npckillpay"] .. " For killing an NPC!")
		end
	end
end

function GM:KeyPress(ply, code)
	self.BaseClass:KeyPress(ply, code)

	if (code == IN_USE) then
		local trace = { }
		trace.start = ply:EyePos()
		trace.endpos = trace.start + ply:GetAimVector() * 95
		trace.filter = ply
		local tr = util.TraceLine(trace)

		if (ValidEntity(tr.Entity) and not ply:KeyDown(IN_ATTACK)) then
			if (tr.Entity:GetTable().Letter) then
				umsg.Start("ShowLetter", ply)
					umsg.Short(tr.Entity:GetNWInt("type"))
					umsg.Vector(tr.Entity:GetPos())
					umsg.String(tr.Entity:GetNWString("content"))
				umsg.End()
			end

			if (tr.Entity:GetTable().MoneyBag) then
				Notify(ply, 0, 4, "You found " .. CUR .. tr.Entity:GetTable().Amount .. "!")
				ply:AddMoney(tr.Entity:GetTable().Amount)
				tr.Entity:Remove()
			end
		else
			umsg.Start("KillLetter", ply)
			umsg.End()
		end
	end
end
